package com.kfyang.manualgear.daoplugin.completion;

import com.intellij.codeInsight.completion.CompletionContributor;
import com.intellij.codeInsight.completion.CompletionParameters;
import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.codeInsight.completion.CompletionType;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.lang.jvm.annotation.JvmAnnotationAttribute;
import com.intellij.lang.jvm.annotation.JvmAnnotationClassValue;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.util.PsiTreeUtil;
import com.kfyang.manualgear.daoplugin.Constants;
import org.jetbrains.annotations.NotNull;

import java.util.List;

public class OrmCompletionContributor extends CompletionContributor {
    @Override
    public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
        if (parameters.getCompletionType() != CompletionType.BASIC)
            return;
        PsiClass parent = PsiTreeUtil.getParentOfType(parameters.getPosition(), PsiClass.class);
        if (parent == null || !parent.isInterface() || !parent.hasAnnotation(Constants.DAO_ANNO)) {
            return;
        }
        List<JvmAnnotationAttribute> attributes = parent.getAnnotation(Constants.DAO_ANNO).getAttributes();

        if (attributes.isEmpty()) {
            return;
        }

        if (!(attributes.get(0).getAttributeValue() instanceof JvmAnnotationClassValue attributeValue)) {
            return;
        }

        Project project = parameters.getPosition().getProject();
        PsiFile originalFile = parameters.getOriginalFile();
        JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);

        String entityName = attributeValue.getQualifiedName();
        int textOffset = parameters.getPosition().getTextOffset();

        String selectText = "%s selectById(int id);".formatted(entityName);
        result.addElement(LookupElementBuilder.create(selectText)
            .withLookupString("select")
            .withPresentableText("select")
            .withInsertHandler((context, item) -> codeStyleManager.shortenClassReferences(originalFile, textOffset, textOffset + selectText.length())));

        String selectAllText = "java.util.List<%s> selectAll();".formatted(entityName);
        result.addElement(LookupElementBuilder.create(selectAllText)
            .withLookupString("selectAll")
            .withPresentableText("selectAll")
            .withInsertHandler((context, item) -> codeStyleManager.shortenClassReferences(originalFile, textOffset, textOffset + selectAllText.length())));

        String insertText = "int insert(%s entity);".formatted(entityName);
        result.addElement(LookupElementBuilder.create(insertText)
            .withLookupString("insert")
            .withPresentableText("insert")
            .withInsertHandler((context, item) -> codeStyleManager.shortenClassReferences(originalFile, textOffset, textOffset + insertText.length())));

        String insertAllText = "int insertAll(List<%s> entityList);".formatted(entityName);
        result.addElement(LookupElementBuilder.create(insertAllText)
            .withLookupString("insertAll")
            .withPresentableText("insertAll")
            .withInsertHandler((context, item) -> codeStyleManager.shortenClassReferences(originalFile, textOffset, textOffset + insertAllText.length())));

        String updateText = "int update(%s entity);".formatted(entityName);
        result.addElement(LookupElementBuilder.create(updateText)
            .withLookupString("update")
            .withPresentableText("update")
            .withInsertHandler((context, item) -> codeStyleManager.shortenClassReferences(originalFile, textOffset, textOffset + updateText.length())));

        String deleteText = "int deleteById(int id);";
        result.addElement(LookupElementBuilder.create(deleteText)
            .withLookupString("delete")
            .withPresentableText("delete"));

        String deleteAllText = "int deleteByIds(java.util.List<Integer> ids);";
        result.addElement(LookupElementBuilder.create(deleteAllText)
            .withLookupString("deleteAll")
            .withPresentableText("deleteAll")
            .withInsertHandler((context, item) -> codeStyleManager.shortenClassReferences(originalFile, textOffset, textOffset + deleteAllText.length())));
    }
}
